package com.up2566.demo.service;

import com.up2566.demo.enums.DataEnum;
import com.up2566.demo.model.ComputeDataModel;
import com.up2566.demo.model.ComputePojo;
import com.up2566.demo.model.DynamicInitDataModel;
import com.up2566.demo.model.TemplateModel;
import com.up2566.demo.model.dto.ComputeDto;
import com.up2566.demo.model.vo.ComputeVo;
import java.math.BigDecimal;
import org.springframework.stereotype.Service;

/**
 * 木桩计算service
 *
 * @author up
 * @date 2021/1/11
 */
@Service
public class ComputeService {

    public ComputeVo compute(ComputeDto dto) {
        ComputePojo result = new ComputePojo(dto.getLiupai(), dto.getSdsej());
        TemplateModel templateModel = TemplateModel.init(dto);
        ComputeDataModel computeData = ComputeDataModel.getComputeData(dto);
        computeA(result, templateModel, computeData, new DynamicInitDataModel().init(computeData.getZuiZhongPro().floatValue()));
        computeB(result, templateModel, computeData, new DynamicInitDataModel().init(computeData.getZuiZhong().floatValue()));
        return result.getVo();
    }

    /**
     * 计算器前一分钟木桩数据
     */
    public void computeA(ComputePojo result, TemplateModel templateModel, ComputeDataModel computeData,
        DynamicInitDataModel dynamicInitData) {
        computeYingZiData(result, computeData.getBlByZj(), templateModel.getYzCountA(), computeData.getZuiZhongPro(),
            dynamicInitData.getYing(),
            computeData.getBlByHx(), computeData.getBlBySp());
        computeLeftProData(result, templateModel.getLeftProCountA(), computeData.getZuiZhongPro(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeTaData(result, templateModel.getTaCountA(), dynamicInitData.getTa(), computeData.getZuiZhongPro(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeTlzData(result, computeData.getBlByZj(), templateModel.getTlzCountA(), computeData.getZuiZhongPro(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeOtherData(result, computeData.getZuiZhongPro(), computeData.getBlByHx(), computeData.getBlBySp(), true);
        if ("0".equals(result.getLiupai())) {
            computeZhuanData(result, templateModel.getZhuanCountA(), computeData.getZuiZhongPro(), computeData.getBlByHx(),
                computeData.getBlBySp(), true);
            computeJyDataByYing(result, computeData.getBlByZj(), templateModel.getJyCountA(), dynamicInitData.getJuan(),
                computeData.getZuiZhongPro(), computeData.getBlByHx(), computeData.getBlBySp());
        } else {
            computeJyDataByHao(result, computeData.getBlByZj(), templateModel.getJyCountA(), templateModel.getJyCountA1(),
                templateModel.getJyCountA2(), dynamicInitData.getJuan(), computeData.getZuiZhongPro(), computeData.getBlByHx(),
                computeData.getBlBySp());
        }

    }

    /**
     * 计算器后四分钟木桩数据
     */
    public void computeB(ComputePojo result, TemplateModel templateModel, ComputeDataModel computeData,
        DynamicInitDataModel dynamicInitData) {
        computeYingZiData(result, computeData.getBlByZj(), templateModel.getYzCountB(), computeData.getZuiZhong(),
            dynamicInitData.getYing(),
            computeData.getBlByHx(), computeData.getBlBySp());
        computeLeftProData(result, templateModel.getLeftProCountB(), computeData.getZuiZhong(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeTaData(result, templateModel.getTaCountB(), dynamicInitData.getTa(), computeData.getZuiZhong(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeTlzData(result, computeData.getBlByZj(), templateModel.getTlzCountB(), computeData.getZuiZhong(), computeData.getBlByHx(),
            computeData.getBlBySp());
        computeOtherData(result, computeData.getZuiZhong(), computeData.getBlByHx(), computeData.getBlBySp(), false);
        if ("0".equals(result.getLiupai())) {
            computeZhuanData(result, templateModel.getZhuanCountB(), computeData.getZuiZhong(), computeData.getBlByHx(),
                computeData.getBlBySp(), false);
            computeJyDataByYing(result, computeData.getBlByZj(), templateModel.getJyCountB(), dynamicInitData.getJuan(),
                computeData.getZuiZhong(), computeData.getBlByHx(), computeData.getBlBySp());
        } else {
            computeJyDataByHao(result, computeData.getBlByZj(), templateModel.getJyCountB(), templateModel.getJyCountB1(),
                templateModel.getJyCountB2(), dynamicInitData.getJuan(), computeData.getZuiZhong(), computeData.getBlByHx(),
                computeData.getBlBySp());
        }
    }

    /**
     * 计算影子伤害
     *
     * @param blByZj  专精比率
     * @param yzCount 影子次数
     * @param gj      攻击力
     * @param ying    影子动态收益
     * @param hx      会心率
     * @param sp      识破率
     */
    private void computeYingZiData(ComputePojo result, BigDecimal blByZj, BigDecimal yzCount, BigDecimal gj, BigDecimal ying, BigDecimal hx,
        BigDecimal sp) {
        BigDecimal yzHxCount = yzCount.multiply(hx);
        BigDecimal yzNoHxCount = yzCount.subtract(yzHxCount);
        BigDecimal yzBase = gj.multiply(ying)
            .multiply((blByZj.multiply(DataEnum.YZ.value()).add(BigDecimal.ONE))).multiply(DataEnum.LSSH.value())
            .multiply(DataEnum.BL_DH.value());
        if ("0".equals(result.getLiupai())) {
            yzBase = yzBase.multiply(new BigDecimal("1.5"));
        }
        BigDecimal yzHx = yzHxCount.multiply(yzBase).multiply(DataEnum.BL_HXSH.value());
        BigDecimal yzNoHx = yzNoHxCount.multiply(yzBase);
        yzNoHx = yzNoHx.subtract(yzNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal yzSh = yzHx.add(yzNoHx);
        result.addShYz(yzSh);
        result.addShYzA(yzHx);
        result.addShYzB(yzNoHx);
    }

    /**
     * 计算惊风-狂伤害
     */
    private void computeLeftProData(ComputePojo result, BigDecimal leftProCount, BigDecimal gj, BigDecimal hx, BigDecimal sp) {
        BigDecimal leftProHxCount = leftProCount.multiply(hx);
        BigDecimal leftProNoHxCount = leftProCount.subtract(leftProHxCount);
        BigDecimal leftProBase = gj.multiply(DataEnum.LEFT_PRO.value()).multiply(DataEnum.LSSH.value()).multiply(DataEnum.BL_DH.value());
        BigDecimal leftProHx = leftProHxCount.multiply(leftProBase).multiply(DataEnum.BL_HXSH.value());
        BigDecimal leftProNoHx = leftProNoHxCount.multiply(leftProBase);
        leftProNoHx = leftProNoHx.subtract(leftProNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal leftProSh = leftProHx.add(leftProNoHx);
        result.addShLeftPro(leftProSh);
    }

    /**
     * 计算踏日伤害
     */
    private void computeTaData(ComputePojo result, BigDecimal taCount, BigDecimal ta, BigDecimal gj, BigDecimal hx, BigDecimal sp) {
        BigDecimal taBaseSh = gj.multiply(ta).multiply(DataEnum.LSSH.value()).multiply(DataEnum.BL_DH.value());
        BigDecimal taHx = taCount.multiply(hx).multiply(taBaseSh).multiply(DataEnum.BL_HXSH.value());
        BigDecimal taNoHx = taCount.multiply(BigDecimal.ONE.subtract(hx)).multiply(taBaseSh);
        taNoHx = taNoHx.subtract(taNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal taSh = taHx.add(taNoHx);
        result.addShTa(taSh);
    }

    /**
     * 计算贪狼斩伤害
     */
    private void computeTlzData(ComputePojo result, BigDecimal blByZj, BigDecimal tlzCount, BigDecimal gj, BigDecimal hx, BigDecimal sp) {
        BigDecimal tlzBl = blByZj.add(BigDecimal.ONE).multiply(DataEnum.JY.value());
        BigDecimal zhanBase = gj.multiply(DataEnum.BL_TLZ.value()).multiply(tlzBl).multiply(DataEnum.LSSH.value())
            .multiply(DataEnum.BL_DH.value());
        BigDecimal zhanHx = tlzCount.multiply(hx).multiply(zhanBase).multiply(DataEnum.BL_HXSH.value());
        BigDecimal zhanNoHx = tlzCount.multiply(BigDecimal.ONE.subtract(hx)).multiply(zhanBase);
        zhanNoHx = zhanNoHx.subtract(zhanNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal zhanSh = zhanHx.add(zhanNoHx);
        result.addShTlz(zhanSh);
    }

    /**
     * 计算其他技能伤害
     */
    private void computeOtherData(ComputePojo result, BigDecimal gj, BigDecimal hx, BigDecimal sp, boolean isFirst) {
        BigDecimal count = isFirst ? new BigDecimal("6") : new BigDecimal("30");
        BigDecimal otherSh = gj.multiply(count).multiply(BigDecimal.ONE.add(hx).multiply(DataEnum.BL_HXSH.value()));
        otherSh = otherSh.subtract(otherSh.multiply(sp).multiply(DataEnum.BL_SP.value()));
        result.addDamage(otherSh);
    }

    /**
     * 计算疾风幻影伤害
     */
    private void computeZhuanData(ComputePojo result, BigDecimal zhuan, BigDecimal gj, BigDecimal hx, BigDecimal sp, boolean isFirst) {
        BigDecimal zhuanBase = gj.multiply(DataEnum.BL_ZHUAN.value()).multiply(DataEnum.LSSH.value()).multiply(DataEnum.BL_DH.value());
        int zhuanCount = zhuan.intValue();
        BigDecimal zhuanSh = BigDecimal.ZERO;
        if (isFirst) {
            for (int i = 1; i <= zhuanCount; i++) {
                if (i > 1 && i <= 5) {
                    zhuanSh = zhuanSh.add(zhuanBase.multiply(BigDecimal.ONE.add(BigDecimal.valueOf(i).multiply(new BigDecimal("0.1")))));
                } else if (i > 5) {
                    zhuanSh = zhuanSh.add(zhuanBase.multiply(new BigDecimal("1.5")));
                }
            }
        } else {
            BigDecimal zhuan_max;
            for (int i = 1; i <= zhuanCount; i++) {
                if (i <= 30) {
                    zhuanSh = zhuanSh.add(zhuanBase.multiply(BigDecimal.ONE.add(new BigDecimal("0.1"))));
                } else {
                    zhuan_max = zhuanBase.multiply(new BigDecimal("1.46"));
                    zhuanSh = zhuanSh.add(zhuan_max);
                }
            }
        }
        BigDecimal zhuanHx = zhuanSh.multiply(hx).multiply(DataEnum.BL_HXSH.value());
        BigDecimal zhuanNoHx = zhuanSh.multiply(BigDecimal.ONE.subtract(hx));
        zhuanNoHx = zhuanNoHx.subtract(zhuanNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        zhuanSh = zhuanHx.add(zhuanNoHx);
        if (result.isSdsej()) {
            zhuanSh = zhuanSh.multiply(new BigDecimal("1.45"));
        }
        result.addShZhuan(zhuanSh);
    }

    /**
     * 计算卷云伤害 -- 纯影
     */
    private void computeJyDataByYing(ComputePojo result, BigDecimal blByZj, BigDecimal jyCount, BigDecimal jy, BigDecimal gj, BigDecimal hx,
        BigDecimal sp) {
        BigDecimal jyBase = gj.multiply(jy).multiply(blByZj.multiply(DataEnum.JY.value()).add(BigDecimal.ONE))
            .multiply(DataEnum.LSSH.value()).multiply(DataEnum.BL_DH.value());
        BigDecimal jyHx = jyCount.multiply(hx).multiply(jyBase).multiply(DataEnum.BL_HXSH.value());
        BigDecimal jyNoHx = jyCount.multiply(BigDecimal.ONE.subtract(hx)).multiply(jyBase);
        jyNoHx = jyNoHx.subtract(jyNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal jySh = jyHx.add(jyNoHx);
        result.addShJy(jySh);
        result.addShJyA(jyHx);
        result.addShJyB(jyNoHx);
    }

    /**
     * 计算卷云伤害 -- 豪
     */
    private void computeJyDataByHao(ComputePojo result, BigDecimal blByZj, BigDecimal jyCount, BigDecimal jyCount1, BigDecimal jyCount2,
        BigDecimal jy, BigDecimal gj, BigDecimal hx, BigDecimal sp) {
        // 豪斩伤害修正
        BigDecimal jyBase = gj.multiply(jy).multiply(blByZj.multiply(DataEnum.JY.value()).add(BigDecimal.ONE))
            .multiply(DataEnum.LSSH.value()).multiply(DataEnum.BL_DH.value()).multiply(new BigDecimal("1.0876"));
        BigDecimal jyHx = jyCount.multiply(hx).multiply(jyBase).multiply(DataEnum.BL_HXSH.value());
        BigDecimal jy_Hx = hx;
        BigDecimal bl_hxsh_1 = DataEnum.BL_HXSH.value();
        if (result.isSdsej()) {
            jy_Hx = jy_Hx.add(new BigDecimal("0.35"));
            bl_hxsh_1 = bl_hxsh_1.add(new BigDecimal("0.1"));
        }
        jyHx = jyHx.add(jyCount1.multiply(jy_Hx).multiply(jyBase).multiply(bl_hxsh_1).multiply(new BigDecimal("1.2")));
        jyHx = jyHx.add(jyCount2.multiply(hx).multiply(jyBase).multiply(DataEnum.BL_HXSH.value()).multiply(new BigDecimal("1.2")));
        BigDecimal jyNoHx = jyCount.multiply(BigDecimal.ONE.subtract(hx)).multiply(jyBase);
        jyNoHx = jyNoHx.add(jyCount1.multiply(BigDecimal.ONE.subtract(jy_Hx)).multiply(jyBase).multiply(new BigDecimal("1.2")));
        jyNoHx = jyNoHx.add(jyCount2.multiply(BigDecimal.ONE.subtract(hx)).multiply(jyBase).multiply(new BigDecimal("1.2")));
        jyNoHx = jyNoHx.subtract(jyNoHx.multiply(sp).multiply(DataEnum.BL_SP.value()));
        BigDecimal jySh = jyHx.add(jyNoHx);
        result.addShJy(jySh);
        result.addShJyA(jyHx);
        result.addShJyB(jyNoHx);
    }

}
